<?php
/*------------------------------------------------------------------------------
part of djangoTpl library
tags
	comment
	cycle
	filter
	firstof
	for
	if
	ifequal
	switch
		case
		default


Copyright (C) 2006 J.Ducastel <jducastel@jducastel.fr>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
------------------------------------------------------------------------------*/

/**
* 'comment' tag node
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_comment extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/

	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	* /
	function buildFromTokens($selfToken,&$nextTokens) {
		$this->token=&$selfToken;
		
		return true;
	}/**/
	
	/**
	* renders as string
	* @access public
	* @return string
	*/
	function render() {
		return '';
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	//var //
	
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/

}

/**
* tag node : for loop
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_for extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	*/
	function buildFromTokens(&$selfToken, &$nextTokens) {
		// $this->token=&$selfToken;
		$def=$selfToken->tagdef;
		$regex='([^ ]+) in ([^ ]+)( reversed)?';
		if (ereg($regex,$def,$search)) {
			$this->alias=$search[1];
			$this->source=$search[2];
			$this->reversed=$search[3]?true:false;
		} else {
			// error !
			trigger_error('invalid structure for tag for : '.$def);
		}
		$this->buildChildNodesFromTokens($nextTokens);
		return true;
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* 
	* @param djangoTplContext
	* @access public
	* @return string
	*/
	function render(&$context) {
		$rendered='';
		// getting list item keys
		if (!$keys=$context->getKeys($this->source)) {
			trigger_error("djangoTpl: for: {$this->source} has no childs");
			return $rendered;
		}
		// reverse loop ?
		if ($this->reversed)
			$keys=array_reverse($keys);
		// looping items
		$counter=0; $total=count($keys);
		foreach ($keys as $key) {
			// setting alias
			$context->setPathAlias($this->source.'.'.$key,$this->alias);
			// setting loop vars
			$counter++;
			$context->setPath('forloop',array());
			$context->setPath('forloop.counter',$counter);
			$context->setPath('forloop.counter0',$counter-1);
			$context->setPath('forloop.revcounter',$total-$counter+1);
			$context->setPath('forloop.revcounter0',$total-$counter);
			$context->setPath('forloop.first',$counter==1);
			$context->setPath('forloop.last',$counter==$total);
			//echo wakdebug::vardump($context);
			// rendering content
			$rendered.=$this->renderChildNodes($context);
		}
		return $rendered;
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	var $tagname='for';

}

/**
* tag node : if
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_if extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	*/
	function buildFromTokens(&$selfToken, &$nextTokens) {
		// importing def
		$this->def=$selfToken->tagdef;
		$this->buildChildNodesFromTokens($nextTokens);
		// getting if child nodes
		//$this->ifnodes=djangoTplParser::tokensToNodesUntilTag
		// getting else child nodes
		
		return true;
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return string
	*/
	function render(&$context) {
		// parsing def
		$words=explode(' ',$this->def);
		//echo wakdebug::vardump($words);
		$notFlag=false;
		$assoc=null;
		// $globalFlag=null;
		$values=array();
		// looping words
		foreach ($words as $word) {
			//echo $word;
			// var or control word ?
			if ($word=='not') {
				$notFlag=true;
			} else if ($word=='and' or $word=='or') {
				if (!$assoc)
					$assoc=$word;
			} else {
				// evaluating var
				//echo "getting $word";
				$value=djangoTplPArser::evalExpression($context,$word);
				//$value=$context->getPath($word);
				//echo wakdebug::vardump($value);
				$bool=$value?true:false;
				// is "not" flag active ?
				if ($notFlag)
					$bool=!$bool;
				// resetting "not" flag
				$notFlag=false;
				$values[]=$bool;
			}
		}
		//echo wakdebug::vardump($values);
		// global evaluating
		switch ($assoc) {
			case 'or':
				// only 1 value need to be true
				if (in_array(true,$values))
					return $this->renderChildNodesBeforeTag($context,'else');
				else
					return $this->renderChildNodesAfterTag($context,'else');
				break;
			case 'and':
			case null:
				// all values need to be true
				if (in_array(false,$values))
					return $this->renderChildNodesAfterTag($context,'else');
				else
					return $this->renderChildNodesBeforeTag($context,'else');
				break;
		}
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	var $tagname='if';
	
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
}

/**
* 'cycle' tag node
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_cycle extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	*/
	function buildFromTokens(&$selfToken) {
		$def=$selfToken->tagdef;
		$this->values=explode(',',$def);
		return true;
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return true;
	}/**/
	
	/**
	* renders node to string
	* @param
	* @access public
	* @return string
	*/
	function render(&$context) {
		$rendered=current($this->values);
		if (!next($this->values))
			reset($this->values);
		return $rendered;
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var array values to cycle through
	*/
	var $values=array();
	var $tagname='cycle';
}

/**
* 'firstof' tag
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_firstOf extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	*/
	function buildFromTokens(&$selfToken) {
		$def=$selfToken->tagdef;
		$this->vars=explode(' ',$def);
		return true;
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return true;
	}/**/
	
	/**
	* renders as string
	* @param djangoTplContext &$context
	* @access public
	* @return string
	*/
	function render(&$context) {
		foreach ($this->vars as $var) {
			if ($value=$context->getPath($var))
				return strval($value);
		}
		return '';
	}/**/
	
	var $tagname='firstof';
}

/**
* filter tag
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_filter extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	*/
	function buildFromTokens(&$selfToken,&$nextTokens) {
		// parsing token
		$this->filters=explode('|',$selfToken->getTagDef());
		// getting child nodes
		$this->buildChildNodesFromTokens($nextTokens);
		return true;
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* renders as string
	* @param djangoTplContext &$context
	* @access public
	* @return string
	*/
	function render(&$context) {
		// rendering child nodes content
		$rendered=$this->renderChildNodes($context);
		// applying filters
		foreach ($this->filters as $filter)
			$rendered=djangoTplParser::applyFilter($rendered,$filter);
		return $rendered;
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	var $tagname='filter';
}

/**
*
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_ifEqual extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	*/
	function buildFromTokens(&$selfToken,&$nextTokens) {
		// parsing def
		$operandRegex='([^" ]+)|("[^"]*")';
		//$this->operands=explode(' ',$selfToken->getTagDef());
		if (ereg('^('.$operandRegex.') ('.$operandRegex.')$',$selfToken->getTagDef(),$search)) {
			// operands are at index 1 and 5
			//echo wakdebug::vardump($search);
			$this->operand1=$search[1];
			$this->operand2=$search[4];
		}
		
		$this->buildChildNodesFromTokens($nextTokens);
		return true;
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* 
	* @param djangoTplContext &$context
	* @access public
	* @return string
	*/
	function render(&$context) {
		$value1=djangoTplParser::evalexpression($context,$this->operand1);
		$value2=djangoTplParser::evalexpression($context,$this->operand2);
		//echo wakdebug::vardump($value1).'='.wakdebug::vardump($value2).' ?';
		//echo $this->operand1.wakaffvar($value1).'?='.$this->operand2.wakaffvar($value2);
		if ($value1==$value2) {
			//echo wakdebug::vardump($value1).'='.wakdebug::vardump($value2);
			return $this->renderChildNodesBeforeTag($context,'else');
		} else
			return $this->renderChildNodesAfterTag($context,'else');
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	var $tagname='ifequal';
	var $operand1;
	var $operand2;
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* checks operands equality
	* @param
	* @access private
	* @return mixed
	* /
	function getValue(&$context,$operand) {

	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
}

/**
*
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_switch extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	*/
	function buildFromTokens(&$selfToken,&$nextTokens) {
		$this->tagname=$selfToken->getTagName();
		$this->tagdef=$selfToken->getTagDef();
		$this->buildChildNodesFromTokens($nextTokens);
		//echo wakaffvar($this);
		return true;
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* renders node as text
	* @param djangoTplContext &$context
	* @access public
	* @return 
	*/
	function render(& $context) {
		// evaluating switcher expression
		$switcherExpression=$this->tagdef;
		// searching for case
		foreach ($this->childnodes as $node) {
			if ($node->isTag() 
			and $node->getTagName()=='case'
			and $node->compareExpression($context,$switcherExpression))
				return $node->render($context);
		}
		// searching for default
		foreach ($this->childnodes as $node) {
			if ($node->isTag() and $node->getTagName()=='default')
				return $node->render($context);
		}
		return '';
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	//var //
	
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
}

/**
*
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_case extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	* /
	function buildFromTokens() {
		
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	*/
	function render(&$context) {
		return $this->renderChildNodes($context);
	}/**/
	
	/**
	* compares expression's value with self value
	* @access public
	* @param djangotplcontext &$context
	* @param string expression
	* @return bool
	*/
	function compareExpression(&$context,$expression) {
		$value=djangoTplParser::evalExpression($context,$expression);
		$selfValue=djangoTplParser::evalExpression($context,$this->tagdef);
		return $value==$selfValue;
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	//var //
	
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
}

/**
*
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
class djangoTplTagNode_default extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	* /
	function buildFromTokens() {
		
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	*/
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	* /
	function render() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	//var //
	
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
}

/**
*
* @author J.Ducastel <jducastel@jducastel.fr>
* @version 
*/
//class djangoTplTagNode_ extends djangoTplTagNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* real constructor
	* @access
	* /
	function __construct() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* builds itself from tokens
	* @param djangoTplToken &$selfToken
	* @param array &$nextTokens djangoTplToken
	* @access public
	* @return bool
	* /
	function buildFromTokens() {
		
	}/**/

	/**
	* is the node atomic (has no children)
	* @access public
	* @return bool
	* /
	function isAtomic() {
		return false;
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	* /
	function render() {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var type desc
	*/
	//var //
	
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
//}
?>
